package com.jeesite.maven.plugin.compressor;

import java.io.File;
import java.util.Collection;
import java.util.HashSet;

import junit.framework.TestCase;

import org.codehaus.plexus.util.FileUtils;
import org.sonatype.plexus.build.incremental.DefaultBuildContext;

public class AggregationTestCase extends TestCase {
	
	private File dir;

	private DefaultBuildContext defaultBuildContext = new DefaultBuildContext();

	@Override
	protected void setUp() throws Exception {
		dir = File.createTempFile(this.getClass().getName(), "-test");
		dir.delete();
		dir.mkdirs();
	}

	@Override
	protected void tearDown() throws Exception {
		FileUtils.deleteDirectory(dir);
	}

	public void test0to1() throws Exception {
		Aggregation target = new Aggregation();
		target.output = new File(dir, "output.js");

		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertFalse(target.output.exists());

		target.includes = new String[] {};
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertFalse(target.output.exists());

		target.includes = new String[] { "**/*.js" };
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertFalse(target.output.exists());
	}

	public void test1to1() throws Exception {
		File f1 = new File(dir, "01.js");
		FileUtils.fileWrite(f1.getAbsolutePath(), "1");
		Aggregation target = new Aggregation();
		target.output = new File(dir, "output.js");
		target.includes = new String[] { f1.getName() };

		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1), FileUtils.fileRead(target.output));
	}

	public void test2to1() throws Exception {
		File f1 = new File(dir, "01.js");
		FileUtils.fileWrite(f1.getAbsolutePath(), "1");

		File f2 = new File(dir, "02.js");
		FileUtils.fileWrite(f2.getAbsolutePath(), "22\n22");

		Aggregation target = new Aggregation();
		target.output = new File(dir, "output.js");

		target.includes = new String[] { f1.getName(), f2.getName() };
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1) + FileUtils.fileRead(f2), FileUtils.fileRead(target.output));

		target.output.delete();
		target.includes = new String[] { "*.js" };
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1) + FileUtils.fileRead(f2), FileUtils.fileRead(target.output));
	}

	public void testNoDuplicateAggregation() throws Exception {
		File f1 = new File(dir, "01.js");
		FileUtils.fileWrite(f1.getAbsolutePath(), "1");

		File f2 = new File(dir, "02.js");
		FileUtils.fileWrite(f2.getAbsolutePath(), "22\n22");

		Aggregation target = new Aggregation();
		target.output = new File(dir, "output.js");

		target.includes = new String[] { f1.getName(), f1.getName(), f2.getName() };
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1) + FileUtils.fileRead(f2), FileUtils.fileRead(target.output));

		target.output.delete();
		target.includes = new String[] { f1.getName(), "*.js" };
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1) + FileUtils.fileRead(f2), FileUtils.fileRead(target.output));
	}

	public void test2to1Order() throws Exception {
		File f1 = new File(dir, "01.js");
		FileUtils.fileWrite(f1.getAbsolutePath(), "1");

		File f2 = new File(dir, "02.js");
		FileUtils.fileWrite(f2.getAbsolutePath(), "2");

		Aggregation target = new Aggregation();
		target.output = new File(dir, "output.js");

		target.includes = new String[] { f2.getName(), f1.getName() };
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f2) + FileUtils.fileRead(f1), FileUtils.fileRead(target.output));
	}

	public void test2to1WithNewLine() throws Exception {
		File f1 = new File(dir, "01.js");
		FileUtils.fileWrite(f1.getAbsolutePath(), "1");

		File f2 = new File(dir, "02.js");
		FileUtils.fileWrite(f2.getAbsolutePath(), "22\n22");

		Aggregation target = new Aggregation();
		target.output = new File(dir, "output.js");
		target.insertNewLine = true;
		target.includes = new String[] { f1.getName(), f2.getName() };

		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1) + "\n" + FileUtils.fileRead(f2) + "\n", FileUtils.fileRead(target.output));
	}

	public void testAbsolutePathFromInside() throws Exception {
		File f1 = new File(dir, "01.js");
		FileUtils.fileWrite(f1.getAbsolutePath(), "1");

		File f2 = new File(dir, "02.js");
		FileUtils.fileWrite(f2.getAbsolutePath(), "22\n22");

		Aggregation target = new Aggregation();
		target.output = new File(dir, "output.js");

		target.includes = new String[] { f1.getAbsolutePath(), f2.getName() };
		assertFalse(target.output.exists());
		target.run(null, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1) + FileUtils.fileRead(f2), FileUtils.fileRead(target.output));
	}

	public void testAbsolutePathFromOutside() throws Exception {
		File f1 = File.createTempFile("test-01", ".js");
		try {
			FileUtils.fileWrite(f1.getAbsolutePath(), "1");

			File f2 = new File(dir, "02.js");
			FileUtils.fileWrite(f2.getAbsolutePath(), "22\n22");

			Aggregation target = new Aggregation();
			target.output = new File(dir, "output.js");

			target.includes = new String[] { f1.getAbsolutePath(), f2.getName() };
			assertFalse(target.output.exists());
			target.run(null, defaultBuildContext);
			assertTrue(target.output.exists());
			assertEquals(FileUtils.fileRead(f1) + FileUtils.fileRead(f2), FileUtils.fileRead(target.output));
		} finally {
			f1.delete();
		}
	}

	public void testAutoExcludeWildcards() throws Exception {
		File f1 = new File(dir, "01.js");
		FileUtils.fileWrite(f1.getAbsolutePath(), "1");

		File f2 = new File(dir, "02.js");
		FileUtils.fileWrite(f2.getAbsolutePath(), "22\n22");

		Aggregation target = new Aggregation();
		target.autoExcludeWildcards = true;
		target.output = new File(dir, "output.js");

		Collection<File> previouslyIncluded = new HashSet<File>();
		previouslyIncluded.add(f1);

		target.includes = new String[] { f1.getName(), f2.getName() };
		assertFalse(target.output.exists());
		target.run(previouslyIncluded, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f1) + FileUtils.fileRead(f2), FileUtils.fileRead(target.output));

		target.output.delete();
		target.includes = new String[] { "*.js" };
		assertFalse(target.output.exists());
		target.run(previouslyIncluded, defaultBuildContext);
		assertTrue(target.output.exists());
		assertEquals(FileUtils.fileRead(f2), FileUtils.fileRead(target.output));
	}
}
